package cn.websocket.service.impl;

import cn.dev33.satoken.util.SaResult;
import cn.websocket.mapper.FileMapper;
import cn.websocket.pojo.File;
import cn.websocket.pojo.config.MinioProperties;
import cn.websocket.service.MinioService;
import cn.websocket.vo.Result;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

import static cn.websocket.constant.FileConstant.*;

/**
 * <h3>WebSocket</h3>
 * <p></p>
 *
 * @author gdw
 * @since 2025-08-19 15:39:09
 */
@Service
@RequiredArgsConstructor
public class MinioServiceImpl implements MinioService {
    private final MinioClient minioClient;
    private final MinioProperties minioProperties;
    private final FileMapper fileMapper;

    @Override
    //文件上传
    public Result<Object> uploadFile(MultipartFile file) throws Exception {
        Map<String, String> result = new HashMap<>();
        // 原始文件名 + 后缀
        String originalFileName = file.getOriginalFilename();
        String extension = Optional.ofNullable(originalFileName)
                .filter(f -> f.contains("."))
                .map(f -> f.substring(f.lastIndexOf(".") + 1))
                .orElse("")
                .toLowerCase();

        // 生成唯一文件名
        String fileName = UUID.randomUUID() + "_" + originalFileName;

        // 根据扩展名选择桶
        String bucketName;
        switch (extension) {
            case FILE_SUFFIX_JPG:
            case FILE_SUFFIX_JPEG:
            case FILE_SUFFIX_PNG:
            case FILE_SUFFIX_GIF:
                bucketName =BUCKET_NAME_IMAGES;
                break;
            case FILE_SUFFIX_DOC:
            case FILE_SUFFIX_DOCX:
                bucketName = BUCKET_NAME_WORD;
                break;
            case FILE_SUFFIX_PDF:
                bucketName = BUCKET_NAME_PDF;
                break;
            default:
                bucketName = BUCKET_NAME_OTHERS;  // 不识别的后缀放到 others 桶
        }

        // 确保 bucket 存在
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }

        // 上传文件
        try (InputStream inputStream = file.getInputStream()) {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileName)
                            .stream(inputStream, file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build()
            );
        }
        String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
        String fullUrl = minioProperties.getEndpoint() + "/" + bucketName + "/" + encodedFileName;
        if(bucketName.equals(BUCKET_NAME_IMAGES)){
            result.put("url",fullUrl);
            return Result.success(result);
        }else{
            //保存文件信息
            File build = File.builder().fileName(fileName).fileType(extension).fileUrl(fullUrl).build();
            fileMapper.insert(build);
            return Result.success(build);
        }
    }
}
